//
//  NSObject+RuntimeProperty.m
//  Weibo
//
//  Created by student on 16/5/5.
//  Copyright © 2016年 Mcc. All rights reserved.
//

#import "NSObject+RuntimeProperty.h"

#import <objc/runtime.h>
@implementation NSObject (RuntimeProperty)
// runtime 机制
//    OC是运行时语言，只有在程序运行时，才会去确定对象的类型，并调用类与对象相应的方法。利用runtime机制让我们可以在程序运行时动态修改类、对象中的所有属性、方法，就算是私有方法以及私有属性都是可以动态修改的。
//什么是Runtime
//我们写的代码在程序运行过程中都会被转化成runtime的C代码执行，例如[target doSomething];会被转化成objc_msgSend(target, @selector(doSomething));。
//OC中一切都被设计成了对象，我们都知道一个类被初始化成一个实例，这个实例是一个对象。实际上一个类本质上也是一个对象，在runtime中用结构体表示。

// 参考
//    http://www.cnblogs.com/wengzilin/p/4344952.html
//ios获取未知类所有属性和方法
//http://www.sjsjw.com/kf_mobile/article/4_17043_17742.asp

/* 获取对象的所有属性和属性内容 */
-(NSDictionary *)getAllPropertiesAndVaules
{
    NSMutableDictionary *props=[NSMutableDictionary dictionary];
    unsigned int outCount,i;
    objc_property_t *properties=class_copyPropertyList([self class], &outCount);
    for (i=0; i<outCount; i++)
    {
        objc_property_t property=properties[i];
        const char *char_f=property_getName(property);
        NSString *propertyName=[NSString stringWithUTF8String:char_f];
        id propertyValue =[self valueForKey:(NSString *)propertyName];
        if (propertyValue) {
            [props setObject:propertyValue forKey:propertyName];
        }
    }
    free(properties);
    return props;
}

/*获取对象的所有属性*/
-(NSArray *)getAllProperties
{
    u_int count;
    objc_property_t *properties=class_copyPropertyList([self class], &count);
    NSMutableArray *propertiesArray=[NSMutableArray arrayWithCapacity:count];
    
    for (int i=0; i<count; i++)
    {
        const char* propertyName=property_getName(properties[i]);
        [propertiesArray addObject:[NSString stringWithUTF8String:propertyName]];
    }
    free(properties);
    return propertiesArray;
}

/*获取对象的所有方法*/
-(void)getAllMethods
{
    unsigned int mothCout_f=0;
    Method* mothList_f=class_copyMethodList([self class], &mothCout_f);
    for (int i=0; i<mothCout_f; i++)
    {
        Method temp_f=mothList_f[i];
        IMP imp_f=method_getImplementation(temp_f);
        SEL name_f=method_getName(temp_f);
        const char* name_s =sel_getName(method_getName(temp_f));
        int arguments = method_getNumberOfArguments(temp_f);
        const char* encoding =method_getTypeEncoding(temp_f);
        NSLog(@"方法名：%@,参数个数：%d,编码方式：%@",[NSString stringWithUTF8String:name_s],
              arguments,
              [NSString stringWithUTF8String:encoding]);
    }
    free(mothList_f);
}
- (NSString *)myDescription
{
    NSMutableString *mStr = [[NSMutableString alloc] init];
    NSDictionary *dict = [self getAllPropertiesAndVaules];
    for(NSString *key in dict.allKeys)
    {
        NSString *str = [NSString stringWithFormat:@"%@:%@\n",key,dict[key]];
        [mStr appendString:str];
    }
    return mStr;
}
@end
